# Copyright (c) 2018 Presto Labs Pte. Ltd.
# Author: leon

import hashlib
import hmac
import time

import requests
from urllib.parse import urlencode

from coin.exchange.base.kr_rest.auth_base import AuthKey
from coin.exchange.base.kr_rest.native_private_client_base import NativePrivateClientBase
from coin.exchange.bittrex_v1.kr_rest.native_public_client import BittrexNativePublicClient
from coin.exchange.bittrex_v1.kr_rest.product import extract_quote_from_native_symbol
from coin.exchange.util.order_checker import OrderAmountChecker


class BittrexAuthBase(NativePrivateClientBase):
  def __init__(self, key_file):
    NativePrivateClientBase.__init__(self, url='https://bittrex.com/api/v1.1', timeout=5)

    key = AuthKey.from_file(key_file)
    self.access_token = key.access_key
    self.secret_key = key.secret_key

  def _nonce(self):
    return str(int(round(time.time() * 1000000)))

  def get_apisign(self, request_url):
    return hmac.new(self.secret_key.encode(), request_url.encode(), hashlib.sha512).hexdigest()

  def _query_impl(self, endpoint, params=None):
    key_and_nonce = {'apikey': self.access_token, 'nonce': self._nonce()}
    complete_url = '%s%s&' % (endpoint, urlencode(key_and_nonce))
    if params is not None:
      complete_url += urlencode(params)
    headers = {"apisign": self.get_apisign(complete_url)}
    return requests.get(complete_url, timeout=self.timeout, headers=headers).json()


class BittrexNativePrivateClient(BittrexAuthBase):
  def __init__(self, key_file):
    BittrexAuthBase.__init__(self, key_file)
    self.order_min_trade_sizes = BittrexNativePublicClient().query_MinTradeSize()
    self.order_amount_checker = OrderAmountChecker("USD", 5, 500)

  def query_market_buylimit(self, symbol, price, qty):
    assert qty >= self.order_min_trade_sizes[symbol]
    if extract_quote_from_native_symbol(symbol) == 'USDT':
      self.order_amount_checker.check_amount("USD", price, qty)
    params = {'market': symbol, 'quantity': qty, 'rate': price}
    path = '%s/market/buylimit?' % self.url
    return self._query(path, params)

  def query_market_selllimit(self, symbol, price, qty):
    assert qty >= self.order_min_trade_sizes[symbol]
    if extract_quote_from_native_symbol(symbol) == 'USDT':
      self.order_amount_checker.check_amount("USD", price, qty)
    params = {'market': symbol, 'quantity': qty, 'rate': price}
    path = '%s/market/selllimit?' % self.url
    return self._query(path, params)

  def query_market_cancel(self, uuid):
    params = {'uuid': uuid}
    path = '%s/market/cancel?' % self.url
    return self._query(path, params)

  def query_account_getorder(self, uuid):
    params = {'uuid': uuid}
    path = '%s/account/getorder?' % self.url
    return self._query(path, params)

  def query_account_getopenorders(self, symbol=None):
    path = '%s/market/getopenorders?' % self.url
    if symbol is None:
      return self._query(path)
    else:
      params = {'market': symbol}
      return self._query(path, params)

  def query_account_getorderhistory(self, symbol=None):
    path = '%s/account/getorderhistory?' % self.url
    if symbol is None:
      return self._query(path)
    else:
      params = {'market': symbol}
      return self._query(path, params)

  def query_account_getbalance(self, currency):
    params = {'currency': currency}
    path = '%s/account/getbalance?' % self.url
    return self._query(path, params)

  def query_account_getbalances(self):
    path = '%s/account/getbalances?' % self.url
    return self._query(path)
